
(function(){

	var _scrollObject = null;
	var _scrollDir = 0;
	var _scrollTimer = null;
	var _SCROLL_INTERVAL = 200;
	var _BTN_HEIGHT = 16;
	var _BTN_WIDTH = 16;
	var _BAR_MIN_SIZE = 16;

	ScrollBar = G.GClass('Widget', 'ScrollBar', G.Base.EventListener);

	ScrollBar.prototype.__init = function(dir) 
	{
		this.__Base__EventListener__init();
		this.dir = dir;
		this.total = 100;
		this.span = 50;
		this.offset = 0;
		this.space = this.total - this.span;
		this.step = 20;
	}

	var _scroll_on_timer = function() {
		if (_scrollObj) {
			if (_scrollDir > 0) {
				_scrollObj.step_inc();
			} else {
				_scrollObj.step_dec();
			}
		} 
	}

	var _scroll_end = function() {
		if (_scrollTimer) {
			clearInterval(_scrollTimer);
			_scrollTimer = null;
		}
		_scrollObj = null;
	}

	ScrollBar.prototype._on_drag = function(ev) {
		var offset = 0;
		var l = ev['left'];
		var t = ev['top'];

		if (this.dir == 'V') {
			var total = this.divBody.clientHeight;
			var span = this.bar.em.offsetHeight;

			if (total == span) {
				offset = 0;
			} else {
				offset = this.space * t / (total - span);
			}
		} else {
			var total = this.divBody.clientWidth;
			var span = this.bar.em.offsetWidth;
			if (total == span) {
				offset = 0;
			} else {
				offset = this.space * l / (total - span);
			}
		}
		this.offset = Math.floor(offset + 0.5);
		this.fire("onscroll", {'offset': this.offset, 'span': this.span, 'total': this.tltal});
	}

	ScrollBar.prototype._resize_v = function() 
	{
		var h = this.divContainer.clientHeight;
		h -= this.btnLU.em.offsetHeight + this.btnRD.em.offsetHeight;
		this.divBody.style.height = h;
		this.reset(this.offset, this.span, this.total);
	}

	ScrollBar.prototype._resize_h = function() 
	{
		var w = this.divContainer.clientWidth;
		w -= this.btnLU.em.offsetWidth + this.btnRD.em.offsetWidth;
		this.divBody.style.width = w;
		this.reset(this.offset, this.span, this.total);
	}


	/*
	 * Set how many to increase when the UP/Down was clicked.
	 */
	ScrollBar.prototype.set_step = function(step) 
	{
		this.step = step;
	}

	/*
	 */
	ScrollBar.prototype.reset = function(offset, span, total) 
	{

		if (span > total)	span = total;

		this.total = total;
		this.span = span;
		this.space = total - span;

		if (this.dir == 'V') {
			var h =  this.divBody.clientHeight * (span / total);
			h = Math.floor(h);
			if (h < _BAR_MIN_SIZE)	h = _BAR_MIN_SIZE;
			this.bar.em.style.height = h;
		} else {
			var w =  this.divBody.clientWidth * (span / total);
			w = Math.floor(w);
			if (w < _BAR_MIN_SIZE)	w = _BAR_MIN_SIZE;
			this.bar.em.style.width = w;
		}
		this.set_offset(offset, false);
	}

	ScrollBar.prototype.set_offset = function(offset, fireEv) 
	{
		if ((offset + this.span) > this.total) {
			offset = this.total - this.span;
		}
		if (offset < 0)		offset = 0;
		this.offset = offset;

		var x = 0;
		var y = 0;
		if (this.dir == 'V') {
			if (this.space != 0) {
				y = offset * (this.divBody.clientHeight - this.bar.em.offsetHeight) / this.space;
			}
			this.bar.em.style.top = y;
		} else {
			if (this.space != 0) {
				x = offset * (this.divBody.clientWidth - this.bar.em.offsetWidth) / this.space;
			}
			this.bar.em.style.left = x;
		}

		if (fireEv) {
			this._on_drag({'top': y, 'left': x});
		}
	}

	ScrollBar.prototype.step_inc = function() 
	{
		var i = this.offset + this.step;
		this.set_offset(i, true);
	}

	ScrollBar.prototype.step_dec = function() 
	{

		if (this.offset > 0) {
			var i = this.offset - this.step;
			this.set_offset(i, true);
		}
	}

	ScrollBar.prototype.render = function(em) 
	{

		var container = document.createElement('div');
		var btnlu = document.createElement('div');
		var btnrd = document.createElement('div');
		var divmid = document.createElement('div');
		var divbar = document.createElement('div');

		divmid.appendChild(divbar);
		container.appendChild(btnlu);
		container.appendChild(divmid);
		container.appendChild(btnrd);
		em.appendChild(container);

		this.divContainer = container;
		this.divBody = divmid;
		this.btnLU = G(btnlu);
		this.btnRD = G(btnrd);
		this.bar = G(divbar);

		if (this.dir == 'V') {
			container.className = "scrollv";
			btnlu.className = "scrollv_up";
			btnrd.className = "scrollv_down";
			divmid.className = "scrollv_mid";

			o = new G(container);
			o.bind("onresize", function(ev) {
				this._resize_v();
			}, this);

			this._resize_v();
		} else {
			container.className = "scrollh";
			btnlu.className = "scrollh_left";
			btnrd.className = "scrollh_right";
			divmid.className = "scrollh_mid";

			o = new G(container);
			o.bind("onresize", function(ev) {
				this._resize_h();
			}, this);
			this._resize_h();
		}
		this.bar.bind("ondrag", this._on_drag, this);

		this.btnRD.bind("onmousedown", this._scroll_rd_start, this);
		this.btnLU.bind("onmousedown", this._scroll_lu_start, this);
		G(document).bind("onmouseup", _scroll_end, this);
	}

	ScrollBar.prototype._scroll_rd_start = function() 
	{
		if (!_scrollTimer) {
			_scrollTimer = setInterval(_scroll_on_timer, _SCROLL_INTERVAL);
		}
		_scrollDir = 1;
		_scrollObj = this;
	}

	ScrollBar.prototype._scroll_lu_start = function() 
	{
		if (!_scrollTimer) {
			_scrollTimer = setInterval(_scroll_on_timer, _SCROLL_INTERVAL);
		}
		_scrollDir = -1;
		_scrollObj = this;
	}


	G.DOM.Element.prototype.ScrollBar = function(dir) {
		scb = new ScrollBar(dir);
		scb.render(this.em);
		return scb;
	}
})()

